package com.intretech.umsin.oss.service.impl;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.intretech.umsin.oss.config.AliyunOSSConfig;
import com.intretech.umsin.oss.entity.FileType;
import com.intretech.umsin.oss.service.MetadataStoreService;
import com.intretech.umsin.oss.vo.FileInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * @version V1.0
 * @ClassName: AliyunOssServiceImpl
 * @Description: AliyunOssServiceImpl 服务实现
 * @author: 李启联
 * @date: 2022-04-25 16:08
 * @Copyright: Copyright (c) 2022
 * 参考资料 https://www.cnblogs.com/codigup/p/10598854.html
 *        https://www.cnblogs.com/captainad/p/10896380.html
 */
@Service
@Slf4j
public class AliyunOssServiceImpl extends AbstractFileService {

    @Autowired(required = false)
    private AliyunOSSConfig aliyunOSSConfig;

    @Autowired(required = false)
    private OSSClient ossClient;

    @Autowired(required = false)
    private MetadataStoreService metadataStoreService;

    /**
     * OSS存储类型
     *
     * @return
     */
    @Override
    public FileType fileType() {
        return FileType.ALIYUN;
    }

    /**
     * 文件元数据存储服务
     *
     * @return
     */
    @Override
    protected MetadataStoreService getMetadataStoreService() {
        return metadataStoreService;
    }

    /**
     * 上传文件
     *
     * @param file
     * @param fileInfo
     */
    @Override
    protected void uploadFile(MultipartFile file, FileInfoVo fileInfo) throws Exception {
        String workDir = aliyunOSSConfig.getFilehost().replace("\\","/");

        workDir = workDir.startsWith("/") ?  workDir.substring(1,workDir.length()) : workDir;
        workDir = workDir.endsWith("/") ?  workDir.substring(0,workDir.length() -1) : workDir;

        if(fileInfo.getFilePathPrefix().length() >1){//设置文件的路径前缀
            String prefix = fileInfo.getFilePathPrefix().replace("\\","/");
            prefix = prefix.startsWith("/") ? prefix : "/"+prefix;
            prefix = prefix.endsWith("/") ? prefix.substring(0,prefix.length() -1) : prefix;
            fileInfo.setFilePathPrefix(workDir + prefix);
        }else{
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String dateCategory =dateTimeFormatter.format(LocalDate.now());
            fileInfo.setFilePathPrefix(workDir + "/"+dateCategory);//工作目录+日期为文件目录
        }

        String fileUrl = fileInfo.getFilePathPrefix() +"/"+ fileInfo.getTagsName();

        try {
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(aliyunOSSConfig.getBucketName(), fileUrl, file.getInputStream()));
            ossClient.setBucketAcl(aliyunOSSConfig.getBucketName(), CannedAccessControlList.PublicRead);
            if(result != null) {
                log.info("Upload result:{}", result.getETag());
                log.info("Upload file {} successfully.", fileInfo.getTagsName());
            }
        }catch (Exception e){
            log.error("Upload file failed.", e);
        }
    }

    /**
     * 删除文件资源
     *
     * @param fileInfo
     * @return
     */
    @Override
    protected boolean deleteFile(FileInfoVo fileInfo) {
        try {
            ossClient.deleteObject(aliyunOSSConfig.getBucketName(),fileInfo.getPath());
            return true;
        }catch (Exception e){
            log.error("delete file failed.", e);
            return false;
        }
    }

    /**
     * 对查询返回的文件列表设置其对应文件访问的URL
     *
     * @param fileInfo
     */
    @Override
    protected void setFileUrl(FileInfoVo fileInfo) {
        fileInfo.setUrl(aliyunOSSConfig.getEndpoint() + fileInfo.getPath());
    }

    /**
     * 下载文件
     *
     * @param fileInfo
     * @return
     */
    @Override
    public byte[] downloadFile(FileInfoVo fileInfo) throws Exception {
        OSSObject ossObject = null;
        InputStream in = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            String filePathName = fileInfo.getPath();
            ossObject = ossClient.getObject(aliyunOSSConfig.getBucketName(), filePathName);
            in = ossObject.getObjectContent();
            IOUtils.copy(in,bos);

            return bos.toByteArray();

        } catch (Exception e) {
            log.error("download file error!", e);
        } finally {
            if (in != null) {
                in.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return null;
    }
}
